package com.zsk;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

/**
 * 逆向工程代码生成器
 * 
 * @author keke
 * @date 2020/07/24
 */
public class CodeGenerator {

    // 表名，多个表之间用逗号分隔
    private final static String dbName = "user_entity,role_entity,user_role_entity,model_entity";
    // 根包名
    private final static String rootPackageName = "com.zsk";
    // 模块名
    private final static String moduleName = "";

    private final static String dbUrl =
        "jdbc:mysql://localhost:3306/test_db?characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false";
    private final static String dbDrive = "com.mysql.jdbc.Driver";
    private final static String dbUser = "amsuser";
    private final static String dbPassword = "ams2018";

    /**
     * 控制台读取器
     * 
     * @param tip
     * @return
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + "：");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！");
    }

    public static void main(String[] args) {
        /**
         * 代码生成器
         */
        AutoGenerator mpg = new AutoGenerator();

        /**
         * 全局配置
         */
        GlobalConfig gc = new GlobalConfig();
        // 生成文件的输出目录
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        // Author设置作者
        gc.setAuthor("keke");
        // 是否覆盖文件
        gc.setFileOverride(true);
        // 生成后打开文件
        gc.setOpen(false);

        // 开启 BaseResultMap
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);
        // 开启二级缓存
        gc.setEnableCache(false);
        // 实体属性 Swagger2 注解
        gc.setSwagger2(true);

        mpg.setGlobalConfig(gc);

        /**
         * 数据源配置
         */
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        // 数据库类型,默认MYSQL
        dataSourceConfig.setDbType(DbType.MYSQL);
        // 自定义数据类型转换
        dataSourceConfig.setTypeConvert(new MySqlTypeConvert());
        dataSourceConfig.setUrl(dbUrl);
        dataSourceConfig.setDriverName(dbDrive);
        dataSourceConfig.setUsername(dbUser);
        dataSourceConfig.setPassword(dbPassword);
        mpg.setDataSource(dataSourceConfig);

        /**
         * 包配置
         */
        PackageConfig pc = new PackageConfig();
        // pc.setModuleName(scanner("模块名"));
        pc.setModuleName(moduleName);
        // 父包名。如果为空，将下面子包名必须写全部， 否则就只需写子包名
        pc.setParent(rootPackageName);
        // 设置包名
        pc.setController("controller").setService("service").setServiceImpl("service.impl").setEntity("entity")
            .setMapper("mapper");

        mpg.setPackageInfo(pc);

        /**
         * 自定义配置
         */
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        /**
         * 模板
         */
        // 如果模板引擎是 freemarker
        // String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        String templatePath = "/templates/mapper.xml.vm";

        /**
         * 自定义输出配置
         */
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectPath + "/src/main/resources/mapper/" + pc.getModuleName() + "/"
                    + tableInfo.getEntityName() + "Mapper.xml";
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        /**
         * 配置模板
         */
        TemplateConfig templateConfig = new TemplateConfig();

        // 配置自定义输出模板
        // 指定自定义模板路径，注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        // templateConfig.setEntity("templates/entity2.java");
        // templateConfig.setService();
        // templateConfig.setController();

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        /**
         * 策略配置
         */
        StrategyConfig strategy = new StrategyConfig();
        // 设置命名格式
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // 表名
        // scanner("model_info,fav_info")
        strategy.setInclude(scanner("请输入数据表名，多张数据表用\",\"分割").split(","));
        // 实体是否为lombok模型（默认 false）
        strategy.setEntityLombokModel(true);
        // 生成 @RestController 控制器
        strategy.setRestControllerStyle(true);
        // 设置自定义继承的Entity类全称，带包名
        strategy.setSuperEntityClass("com.zsk.entity.BaseEntity");
        // 设置自定义继承的Controller类全称，带包名
        // strategy.setSuperControllerClass("com.zsk.contoller.BaseController");
        // 设置自定义基础的Entity类，公共字段
        strategy.setSuperEntityColumns("id");
        // 驼峰转连字符
        strategy.setControllerMappingHyphenStyle(true);
        // 表名前缀
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);

        // 如果选择Freemarker需要以下配置
        // mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }
}
